/**
 *  Transaction.java        22-ott-2009
 *   
 * Copyright (c) 2009 mentalsmash.org
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 *  The use of the Apache License does not indicate that this project is
 *  affiliated with the Apache Software Foundation.
 */

package org.mentalsmash.tazio.transactions.user;

import java.io.Serializable;
import java.util.concurrent.Future;

import org.mentalsmash.tazio.transactions.control.TransactionStateException;
import org.mentalsmash.tazio.transactions.model.identifiers.TID;

/**
 * The Transaction interface allows operations to be performed against the
 * transaction in the target Transaction object. A Transaction object is created
 * corresponding to each global transaction creation. The Transaction object can
 * be used for synchronization registration, transaction completion, and status
 * query operations.
 * 
 * @author Andrea Reale <andrea.reale@gmail.com>
 * @version 0.0.1
 */
public interface Transaction extends Serializable {

    /**
     * Defines an invalid sequence number to temporaly assign to transactions
     */
    final static long INITIAL_SEQNO = 0;

    /**
     * Try to synchronously commit the transaction object represented by this
     * Transaction.
     * <p>
     * The transaction will be locally and globally validated and if the
     * validation process succeeds, the modifications to objects involved in
     * this transaction will be applied to the actual objects in the Share
     * </p>
     * 
     * @throws RollbackException
     *             thrown to indicate that the transaction was not committed,
     *             but was aborted
     * @throws TransactionStateException
     *             thrown when a method of this interface is called while the
     *             transaction is not in a valid method to be called (e.g.
     *             <code>commit()</code> is calle when the transaction is in the
     *             <code>COMMITTED/<code> status
     * @throws TransactionalSystemException
     *             if a general transactional system error occurs
     * @throws RuntimeTransactionException
     *             thrown if the transactions' system encounters any unexpected
     *             problem while committing this Transaction object
     * 
     * 
     */
    void commit() throws RollbackException, TransactionStateException,
	    TransactionalSystemException;

    /**
     * Makes this transaction object abort.
     * 
     * @throws TransactionStateException
     *             if this method is called while this transaction is not in the
     *             {@link TransactionStatus.RUNNING} state.
     */
    void rollback() throws TransactionStateException;

    /**
     * Registers an object implementing the
     * {@link javax.transaction.Synchronization Synchronization} interface to
     * listen for relevant events associated to that transaction's lifecycle.
     * 
     * @param sync
     *            a {@link javax.transaction.Synchronization Synchronization}
     *            implementor that will be notified of events associated with th
     *            transaction
     * @throws RollbackException
     *             thrown if this method is called when this transaction is
     *             marked for being rolled back
     * @see javax.transaction.Synchronization Synchronization
     */
    // void registerSynchronization( Synchronization sync );

    /**
     * Sets the value for this transaction to time out.
     * <p>
     * The timeout value for a transaction is the maximum time that can elapse
     * from transaction's creation time to transaction completion time. If more
     * time then
     * <code>timeout> elapses the transaction will be considered no longer valid,
	 * and will be rolled back
     * </p>
     * 
     * @param seconds
     *            the number of seconds for the timeout value to be set to
     */
    // void setTransactionTimeout( int seconds );

    /**
     * Returns the transaction associated to the invoking thread, if any.
     * <p>
     * If no transaction is currently associated to the thread returns
     * <code>null</code>
     * </p>
     * 
     * @return the transaction associated to the invoking thread, if any.
     */
    // Transaction getCurrent(); <-- Better to be in the TransactionManager

    /**
     * Returns the sytem-unique identifier of the transaction object.
     * 
     * @return the sytem-unique identifier of the transaction object.
     */
    TID getTransactionId();

    /**
     * Returns the status of the Transaction object, which is the phase in which
     * this transaction is at the time this method is invoked.
     * 
     * @return the status of the Transaction object
     */
    TransactionStatus getStatus();

    /**
     * Commits the Transaciton object asynchronously.
     * <p>
     * The control is immediately returned to the caller after this method's
     * invocation, but another thread will perform the actual transaction commit
     * procedure.
     * </p>
     * <p>
     * The outcome of the commit will be available through the
     * {@link java.util.concurrent.Future Future} reference returned by this
     * method, along with exception that may have occurred.
     * </p>
     * 
     * @return a reference to a {@link java.util.concurrent.Future Future}
     *         instance that can be polled to check the outcome of the
     *         transaction
     * @throws TransactionStateException
     *             thrown if the transaction is in an invalid state for this
     *             method to be called.
     */
    Future<TransactionStatus> commitAsync() throws TransactionStateException;

    /**
     * Makes the transaction rollback when the transaction will be asked to
     * commit.
     * <p>
     * This behaviour is different from that of {@link #rollback()} in that
     * <code>setRollbackOnly()</code> does not roll back the transaction
     * immediatly, but it lets it run until {@link #commit()} or
     * {@link #commitAsync()} are invoked.
     * </p>
     */
    void setRollbackOnly();

}
